#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <error.h>
#include <signal.h>
#include <string.h>

#include <termios.h>

#define MAX_NUM_REGS	6
#define MAX_COL	12

struct termios old;
struct termios new;
int running = 1;

unsigned char buffer[512];

char const info[] = "welcome to use! Press 'a' to dispaly all\n";
static unsigned char const KEY_UP[] = {0x1b, 0x5b, 0x41};
static unsigned char const KEY_DOWN[] = {0x1b, 0x5b, 0x42};
static unsigned char const KEY_LEFT[] = {0x1b, 0x5b, 0x44};
static unsigned char const KEY_RIGHT[] = {0x1b, 0x5b, 0x43};

void signal_handle(int sig){
	tcsetattr(0, TCSANOW, &old);
	running = 0;
}

void clear_line(void){
	int i;
	char str = ' ';
	for(i=0; i<MAX_COL; i++){
		write(1, KEY_LEFT, sizeof(KEY_LEFT));
	}
	for(i=0; i<MAX_COL; i++){
		write(1, &str, 1);
	}
	for(i=0; i<MAX_COL; i++){
		write(1, KEY_LEFT, sizeof(KEY_LEFT));
	}
}

int main(int argc, char *argv[])
{
	int ret;
	unsigned char key[6];
	unsigned char str[32];
	unsigned char regs[MAX_NUM_REGS] = {50, 50, 50, 50};
	unsigned char index = MAX_NUM_REGS - 1;
	char i;

	signal(SIGINT, signal_handle);

	ret = tcgetattr(0, &old);
	if(ret){
		perror("tcgetattr() error!");
		exit(1);
	}

	new = old;
	new.c_lflag &= ~(ICANON | ECHO);
	new.c_cc[VMIN]  = 1;
	new.c_cc[VTIME] = 0;

	ret = tcsetattr(0, TCSANOW, &new);
	if(ret){
		perror("tcsetattr() error!");
		exit(2);
	}
	write(1, info, sizeof(info));

	for(i=0; i<MAX_NUM_REGS; i++){
		if(i==MAX_NUM_REGS-1)
			sprintf(str, "*reg[%d]=0x%02x", i, regs[i]);
		else
			sprintf(str, " reg[%d]=0x%02x\n", i, regs[i]);
		write(1, str, strlen(str));
	}
	while(running && (ret = read(0, key, sizeof(key)))){
		/**
		 *  It is strange. When using printf, it must end with '\n' then
		 *  the string will display on the console, else it won't display
		 *  on the console. I spend much time on this, it you know why,
		 *  please tell me, thank you!
		 */
		//printf("%c\n", key);
		//sprintf(str, "0x%02x", key);
		if(ret > 1){
			if(!memcmp(key, KEY_UP, sizeof(KEY_UP))){
				//KEY UP press
				if(index == 0)
					continue;

				clear_line();
				sprintf(str, " reg[%d]=0x%02x", index, regs[index]);
				write(1, str, strlen(str));

				index--;
				write(1, key, sizeof(KEY_UP));

				clear_line();
				sprintf(str, "*reg[%d]=0x%02x", index, regs[index]);
				write(1, str, strlen(str));
				continue;
			}else if(!memcmp(key, KEY_DOWN, sizeof(KEY_DOWN))){
				//KEY DOWN press
				if(index == MAX_NUM_REGS - 1)
					continue;

				clear_line();
				sprintf(str, " reg[%d]=0x%02x", index, regs[index]);
				write(1, str, strlen(str));
				
				index++;
				write(1, key, sizeof(KEY_DOWN));

				clear_line();
				sprintf(str, "*reg[%d]=0x%02x", index, regs[index]);
				write(1, str, strlen(str));
				continue;
			}else if(!memcmp(key, KEY_LEFT, sizeof(KEY_LEFT))){
				//KEY LEFT press
				regs[index]++;
				clear_line();
				sprintf(str, "*reg[%d]=0x%02x", index, regs[index]);
				write(1, str, strlen(str));
				continue;
			}else if(!memcmp(key, KEY_RIGHT, sizeof(KEY_RIGHT))){
				//KEY RIGHT press
				regs[index]--;
				clear_line();
				sprintf(str, "*reg[%d]=0x%02x", index, regs[index]);
				write(1, str, strlen(str));
				continue;
			}else{
				continue;
			}
		}
	}

	ret = tcsetattr(0, TCSANOW, &old);

	return 0;
}
